/* Copyright 2024 Coremail
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * 依赖ohmail对数据库进行操作.
 * 1,创建数据库并创建表
 *
 */
import type { BaseDao, DaoSession, QueryBuilder } from '@ohos/dataorm';
import { DaoMaster } from '@ohos/dataorm';
import { MailDbOpenHelper } from './MailDbOpenHelper';
import util from '@ohos.util';
import type { Context } from '@ohos.abilityAccessCtrl';
import { EntityTransformer } from './EntityTransformer';
import { GlobalContext, Property } from '@ohos/dataorm';
import { MailDaoImpl } from './dao_impl/MailDaoImpl';
import { FolderEntity } from '../entities/FolderEntity';
import { FolderDaoImpl } from './dao_impl/FolderDaoImpl';
import { MailHandlerResultCode } from './MailBaseData';
import type { ActionResult } from './MailBaseData';
import { MailEntity } from '../entities/MailEntity';
import relationalStore from '@ohos.data.relationalStore';
import { BusinessError } from '@ohos.base';
import { getLogger } from '@coremail/mail_base';

const logger = getLogger("MailDbDataOrm");

export class MailDbDataOrm {
  public TAG: string = "MailDbDataOrm"
  public context: Context;
  public dbName = "mails.db";
  private daoSession: DaoSession;
  public mailDaoImpl:MailDaoImpl;
  public folderDaoImpl:FolderDaoImpl;
  public fileRootDir:string;
  // public dbRelativePath:string;
  public accountKey:string
  private account:string

  /**
   *
   * @param context
   * @param name 账号的邮箱
   */
  constructor(context: Context, account: string) {
    let base64 = new util.Base64Helper();
    this.account = account;
    this.accountKey = base64.encodeToStringSync(this.stringToUint8Array(account))
    this.dbName = this.accountKey + ".db";
    this.context = context;
    this.fileRootDir = context.filesDir;
    // this.dbRelativePath = `mail_db`;
  }

  /**
   * 1,创建数据库并创建表
   * 2,并初始化数据库连接
   * 3,初始化dao
   * 4,创建后需要初始化操作.
   */
  async createDb(): Promise<ActionResult<null>> {
    let helper: MailDbOpenHelper = new MailDbOpenHelper(this.context, this.dbName);
    // 设置新的数据库版本,如果新版本中包含表更新实例将在这调用onUpgradeDatabase进行表更新
    helper.setEncrypt(false);
    helper.setEntities(MailEntity, FolderEntity);
    try {
      //获取db并创建所有表.
      const db = await helper.getWritableDb();
      this.daoSession = new DaoMaster(db).newSession();
      // let accountRelativePath = `${this.dbRelativePath}/${this.accountKey}`
      this.mailDaoImpl = new MailDaoImpl(this.daoSession.getBaseDao(MailEntity),this.fileRootDir,this.account);
      this.folderDaoImpl = new FolderDaoImpl(this.daoSession.getBaseDao(FolderEntity));
      // root文件夹需要插入到数据库.
      await this.folderDaoImpl.insertRootFolder().then(()=>{}).catch((e:Error)=>{
        logger.warn(e.message);
      });
      logger.info('__engine', `engine db inited success`)
      return {
        status: MailHandlerResultCode.Ok,
        response: null,
        message: null
      };
    } catch (e) {
      logger.warn(e);
      return {
        status: MailHandlerResultCode.Error,
        response: null,
        message: `${e}`
      }
    }
  }

  /**
   * 删除数据库.
   * @returns
   */
  deleteDb():Promise<void> {
    return relationalStore.deleteRdbStore(this.context, this.dbName);
  }

  async getFolderCount():Promise<number> {
    return this.folderDaoImpl.getCount();
  }

  stringToUint8Array(str: string): Uint8Array {
    let arr: number[] = [];
    for (let i = 0, j = str.length; i < j; ++i) {
      arr.push(str.charCodeAt(i));
    }
    let tmpUint8Array = new Uint8Array(arr);
    return tmpUint8Array
  }

}
